package com.mspbots.core.wise.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mspbots.core.AbstractBaseServiceImpl;
import com.mspbots.core.wise.mapper.TenantUserConfigurationMapper;
import com.mspbots.core.wise.model.TenantUser;
import com.mspbots.core.wise.model.TenantUserConfiguration;
import com.mspbots.core.wise.service.TenantUserConfigurationService;
import com.mspbots.core.wise.service.TenantUserService;
import com.mspbots.cw.request.TenantUserConfigurationDTO;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

/**
 * <p>
 * serviceImpl
 * </p>
 *
 * @author Jun Zhou
 * @since 2019-06-24
 */
@Log4j2
@Service
public class TenantUserConfigurationBaseServiceImpl extends AbstractBaseServiceImpl<TenantUserConfigurationMapper, TenantUserConfiguration>
        implements TenantUserConfigurationService {

    public static final String REDIS_WORKTIME = "MSPBOTS:CONFIG:TENANT:workTimeList";
    @Autowired
    TenantUserService tenantUserService;

    @Override
    public TenantUserConfiguration findByKeyword(TenantUserConfiguration tenantUserConfiguration) {
        QueryWrapper<TenantUserConfiguration> queryWrapper = new QueryWrapper<>(tenantUserConfiguration);
        return this.baseMapper.selectOne(queryWrapper);
    }

    @Override
    public IPage<TenantUserConfigurationDTO> workTimePage(Page<TenantUserConfigurationDTO> page, TenantUserConfiguration query) {
        return baseMapper.workTimePage(page, query);
    }

    @Cacheable(value = REDIS_WORKTIME, key = "#query.tenantId + '_' + #query.keyword", condition = "#query.keyword eq 'work_time'")
    @Override
    public List<TenantUserConfiguration> workTimeList(TenantUserConfiguration query) {
        return this.baseMapper.selectList(new QueryWrapper<>(query));
    }

    @Override
    public Object saveUserDaylightTime(TenantUserConfiguration dto) {
        dto.setKeyword("day_light");
        TenantUserConfiguration daylightParam = new TenantUserConfiguration();
        daylightParam.setTenantId(dto.getTenantId());
        daylightParam.setTenantUserId(dto.getTenantUserId());
        daylightParam.setKeyword("day_light");
        TenantUserConfiguration daylight = findByKeyword(daylightParam);
        if (null != daylight) {
            dto.setId(daylight.getId());
        }
        this.saveOrUpdate(dto);

        dto.setKeyword("work_time");
        TenantUserConfiguration param = new TenantUserConfiguration();
        BeanUtils.copyProperties(dto, param, "id", "keywordValue", "createDate");
        TenantUserConfiguration tufwt = findByKeyword(param);
        ObjectNode wtvalue = null;
        try {
            wtvalue = this.objectMapper.readValue(tufwt.getKeywordValue(), ObjectNode.class);
        } catch (JsonProcessingException e) {
            log.error("saveUserDaylightTime JsonProcessingException");
            e.printStackTrace();
        }
        //current time is daylight
        Boolean isDaylight = TimeZone.getTimeZone(ZoneId.of(ZoneId.SHORT_IDS.get(wtvalue.get("timezone").asText()))).inDaylightTime(new Date());
        //user need to set daylight
        Boolean valBool = Boolean.parseBoolean(dto.getKeywordValue());
        String offSetStr = wtvalue.get("offset").asText().split(":")[0];
        log.debug("offSetStr:::" + offSetStr);
        Integer offset = Integer.parseInt(offSetStr);
        log.debug("offset:::" + offset);
        if (valBool && isDayLightSetting(offset) && isDaylight) {
            if (offset < 0) {
                wtvalue.put("offset", offset + 1 + ":00");
            } else if (offset > 0) {
                wtvalue.put("offset", offset - 1 + ":00");
            }
            //user need to set daylight && db is not daylight && current time is daylight

        } else if (!valBool && !isDayLightSetting(offset) && !isDaylight) {
            //user need to set to NOT daylight && db is daylight && current time is not daylight
            if (offset < 0) {
                wtvalue.put("offset", offset - 1 + ":00");
            } else if (offset > 0) {
                wtvalue.put("offset", offset + 1 + ":00");
            }
        }
        tufwt.setKeywordValue(wtvalue.toString());
        return this.saveOrUpdate(tufwt);
    }


    /**
     * db is daylight
     *
     * @param offset
     * @return
     */
    private Boolean isDayLightSetting(Integer offset) {
        Calendar cal = Calendar.getInstance();
        //获得时区和 GMT-0 的时间差,偏移量
        Integer offsetLocal = cal.get(Calendar.ZONE_OFFSET);
        return !offsetLocal.equals(offset);
    }


    @CacheEvict(value = REDIS_WORKTIME, key = "#query.tenantId + '_' + #query.keyword", condition = "#query.keyword eq 'work_time'")
    @Override
    public TenantUserConfiguration insertOrUpdate(TenantUserConfiguration query) {
        saveOrUpdate(query);
        return query;
    }

    @CacheEvict(value = REDIS_WORKTIME, key = "#list[0].tenantId + '_' + #list[0].keyword", condition = "#list[0].keyword eq 'work_time'")
    @Override
    public Object insertOrUpdateBatch(List<TenantUserConfiguration> list) {
        return saveOrUpdateBatch(list);
    }

    @Override
    public boolean deleteWorkTime(List<Long> userList) {
        Boolean result = this.baseMapper.deleteWorkTime(userList);
        List<TenantUser> tenantUserList = tenantUserService.getMessageSwitch(userList);
        List<TenantUserConfiguration> tenantUserConfigurationList = new ArrayList<>();
        for (TenantUser tenantUser : tenantUserList) {
            TenantUserConfiguration tenantUserConfiguration = new TenantUserConfiguration();
            tenantUserConfiguration.setTenantId(tenantUser.getTenantId());
            tenantUserConfiguration.setTenantUserId(tenantUser.getId());
            tenantUserConfiguration.setKeyword("messages_switch");
            tenantUserConfiguration.setKeywordValue("off");
            tenantUserConfiguration.setCreateDate(LocalDateTime.now());
            tenantUserConfigurationList.add(tenantUserConfiguration);
        }
        return this.saveOrUpdateBatch(tenantUserConfigurationList);
    }
}
